package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustException;
import com.heima.file.config.OssAliyunConfigProperties;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmMaterialDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.threadlocal.WmThreadLocalUtils;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmMaterialService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class WmMaterialServiceImpl extends ServiceImpl<WmMaterialMapper, WmMaterial> implements WmMaterialService {
    @Autowired
    OssAliyunConfigProperties properties;

    /**
     * 条件分页
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findPage(WmMaterialDto dto) {
        //参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        //构建条件执行查询
        LambdaQueryWrapper<WmMaterial> wrapper = Wrappers.<WmMaterial>lambdaQuery();
        if (dto.getIsCollection() == 1) {
            wrapper.eq(WmMaterial::getIsCollection, dto.getIsCollection());
        }
        //必须要是当前登录的用户
        WmUser user = WmThreadLocalUtils.getUser();
        if (user != null) {
            wrapper.eq(WmMaterial::getUserId, user.getId());
        }
        //根据时间排序
        wrapper.orderByDesc(WmMaterial::getCreatedTime);

        //执行分页
        IPage<WmMaterial> page = page(new Page<WmMaterial>(dto.getPage(), dto.getSize()), wrapper);
        //图片回显
        List<WmMaterial> materialList = page.getRecords().stream()
                .map(wmMaterial -> {
                    wmMaterial.setUrl(properties.getWebSite() + wmMaterial.getUrl());
                    return wmMaterial;
                })
//                .filter(wmMaterial -> wmMaterial.getId().equals(1))
//                .sorted(Comparator.comparing(WmMaterial::getId).reversed())
//                .distinct()
                .collect(Collectors.toList());
        return new PageResponseResult(dto.getPage(), dto.getSize(), page.getTotal(), materialList);
    }


    @Autowired
    FileStorageService fileStorageService;  // OSS
    @Value("${file.oss.profix}")
    private String profix;

    /**
     * 上传图片
     *
     * @param multipartFile
     * @return
     */
    @Override
    public ResponseResult upload(MultipartFile multipartFile) {
        //参数校验
        if (multipartFile == null || multipartFile.getSize() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //上传图片oss
        String originalFilename = multipartFile.getOriginalFilename();//获取原始文件名
        //重命名
        String name = UUID.randomUUID().toString().replace("-", "");
        //文件后缀
        String postfix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = name + postfix;
        try {
            //上传
            String fileUrl = fileStorageService.store(profix, fileName, multipartFile.getInputStream());
            //保存上传记录到数据库
            WmMaterial wmMaterial = new WmMaterial();
            wmMaterial.setUrl(fileUrl);
            wmMaterial.setCreatedTime(new Date());
            wmMaterial.setIsCollection((short) 0);
            wmMaterial.setType((short) 0);
            WmUser user = WmThreadLocalUtils.getUser();
            if (user != null) {
                wmMaterial.setUserId(user.getId());
            }
            save(wmMaterial);
            //返回结果
            wmMaterial.setUrl(properties.getWebSite() + fileUrl);
            return ResponseResult.okResult(wmMaterial);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }

    @Autowired
    WmNewsMaterialMapper wmNewsMaterialMapper;

    /**
     * 删除图片
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteById(Integer id) {
        //参数校验
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmMaterial wmMaterial = getById(id);
        if (wmMaterial == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //判断图片是否被文章引用,引用不能删除
        LambdaQueryWrapper<WmNewsMaterial> wrapper = Wrappers.<WmNewsMaterial>lambdaQuery();
        wrapper.eq(WmNewsMaterial::getMaterialId, id);
        Integer count = wmNewsMaterialMapper.selectCount(wrapper);
        if (count > 0) {
            CustException.cust("图片已被使用,无法删除");
        }
        //删除图片
        fileStorageService.delete(wmMaterial.getUrl());
        //删除数据库数据
        removeById(id);

        return ResponseResult.okResult();

    }

    /**
     * 收藏/取消收藏图片
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    public ResponseResult collect(Integer id, Short status) {
        //参数校验
        if (id == null || status == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据id查询图片是否存在
        WmMaterial wmMaterial = getById(id);
        if (wmMaterial == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //更改状态
        wmMaterial.setIsCollection(status);
        updateById(wmMaterial);
        return ResponseResult.okResult();
    }
}
